package service.GatewayService;

import bean.DemoProtocol;
import bean.GatewayProtocol;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import org.apache.log4j.Logger;

import java.util.Date;


/**
 * Created by momochen on 2017-07-18.
 */
public class NettyGatewayTCPServiceHandler extends SimpleChannelInboundHandler<GatewayProtocol> {
    private static Logger logger = Logger.getLogger(NettyGatewayTCPServiceHandler.class);

    static volatile SocketChannel channelService;

    protected void channelRead0(ChannelHandlerContext channelHandlerContext, GatewayProtocol msg) throws Exception {
        if (msg == null) {
            return;
        }

        System.out.println("===>" + msg.getHead() + " " + msg.getSerial() + "  " + msg.getLenght() + "   " + msg.getCmd() + "  " + msg.getCrc());

        if ((msg.getCmd() & 0xFF) == 0xF0) {
            channelService = (SocketChannel) channelHandlerContext.channel();
            System.out.println("===>监控端:" + channelService.remoteAddress());
        } else {
            if (channelService != null) {
                ChannelFuture future = channelService.writeAndFlush(msg);
//                future.addListener(future1 -> System.out.println("==>" + future.isSuccess()));
            }
        }

//        GatewayProtocol gatewayProtocol = new GatewayProtocol();
//        gatewayProtocol.setLenght((short) 9);
//        gatewayProtocol.setDatas(new byte[]{1});

//        ChannelFuture future = channelHandlerContext.writeAndFlush(gatewayProtocol);
//        future.addListener(future1 -> System.out.println("==>" + future.isSuccess()));

//        ChannelFuture future = channelHandlerContext.writeAndFlush(msg);
//        future.addListener(future1 -> System.out.println("==>" + future.isSuccess()));

        ReferenceCountUtil.release(msg);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        String socketString = ctx.channel().remoteAddress().toString();

        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                System.out.println("===>READER_IDLE");
                ctx.disconnect();
            } else if (event.state() == IdleState.WRITER_IDLE) {
                System.out.println("===>WRITER_IDLE");
                ctx.disconnect();
            } else if (event.state() == IdleState.ALL_IDLE) {
                System.out.println("===>ALL_IDLE");
                ctx.disconnect();
            }
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
//        channel = (SocketChannel) ctx.channel();
//        System.out.println("===>handlerAdded");

        System.out.println("===>" + ctx.channel().remoteAddress() + " Connected");
    }

    //客户端关闭
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        System.out.println("===>" + ctx.channel().remoteAddress() + " Disconnect");
        if (ctx.channel() == channelService) {
            channelService = null;
        }
        // 移除
        ctx.close();
//        System.out.println("===>channelInactive");
    }

    //异常消息
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        ctx.close();
        cause.printStackTrace();
//        System.out.println("===>exceptionCaught");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
//        ctx.close();
//        System.out.println("===>channelReadComplete");
    }

    public static String byteTo16(byte bt) {
        String[] strHex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
        String resStr = "";
        int low = (bt & 15);
        int high = bt >> 4 & 15;
        resStr = strHex[high] + strHex[low];
        return resStr;
    }

    public static String bytesToHexString(byte[] src, int lenght) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }

//        int lenght = src.length;
        int size = src.length;
        if (lenght > size) {
            lenght = size;
        }

        for (int i = 0; i < lenght; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv + " ");
        }
        return stringBuilder.toString();
    }
}
